package com.ponhu.ea2.goodsCenter.provider.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ponhu.ea2.constants.DictConstant;
import com.ponhu.ea2.dto.DictItemDataDto;
import com.ponhu.ea2.entity.PhSysDict;
import com.ponhu.ea2.entity.PhSysDictItem;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhSysDictItemMapper;
import com.ponhu.ea2.goodsCenter.provider.service.PhSysDictItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ponhu.ea2.goodsCenter.provider.service.PhSysDictService;
import com.ponhu.ea2.support.exception.BusinessRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.ponhu.ea2.enums.ResponseCodeEnum.*;

/**
 * 字典项 服务实现类
 *
 * @author ${author}
 * @since 2021-10-14
 */
@Slf4j
@Service
public class PhSysDictItemServiceImpl
        extends ServiceImpl<PhSysDictItemMapper, PhSysDictItem>
        implements PhSysDictItemService {

    @Autowired
    private PhSysDictService phSysDictService;

    /**
     * 根据字典类型获取字典项集合
     *
     * @param dictType
     * @return
     */
    @Override
    public List<PhSysDictItem> getDictItemsByType(String dictType) {

        LambdaQueryWrapper<PhSysDictItem> queryWrapper = Wrappers
                .lambdaQuery(PhSysDictItem.class)
                .eq(PhSysDictItem::getType, dictType)
                .orderByAsc(PhSysDictItem::getSort);

        return list(queryWrapper);
    }

    @Override
    public PhSysDictItem getDictItemByValue(String dictType, String value) {
        return this.getOne(Wrappers.lambdaQuery(PhSysDictItem.class)
                .eq(PhSysDictItem::getType, dictType)
                .eq(PhSysDictItem::getValue, value));
    }

    @Override
    public List<PhSysDictItem> getQualityDictList(List<String> dictItemValueList) {
        if (CollectionUtils.isEmpty(dictItemValueList)) {
            return null;
        }

        return getDictItemList(dictItemValueList, DictConstant.CONDITION_TYPE);
    }

    @Override
    public List<PhSysDictItem> getInventorySourceDictList(List<String> dictItemValueList) {
        if (CollectionUtils.isEmpty(dictItemValueList)) {
            return null;
        }

        return getDictItemList(dictItemValueList, DictConstant.INVENTORY_SOURCE);
    }

    @Override
    public List<PhSysDictItem> getInWayDictList(List<String> dictItemValueList) {
        return getDictItemList(dictItemValueList, DictConstant.GOTOWARE_TYPE);
    }

    @Override
    public <T> Map<String, String> getDictItemList(String dictType, List<T> records, Function<T, String> mapper) {
        if (CollectionUtils.isEmpty(records)) {
            return null;
        }

        List<String> dictValueList = records.stream()
                .map(mapper)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(dictValueList)) {
            return null;
        }

        List<PhSysDictItem> dictItemList = getDictItemList(dictValueList, dictType);
        if (CollectionUtils.isEmpty(dictItemList)) {
            return null;
        }

        return dictItemList.stream().collect(Collectors.toMap(PhSysDictItem::getValue, PhSysDictItem::getLabel));
    }

    @Override
    public boolean addOrUpdateDictItem(List<DictItemDataDto> dictItemDataList) {
        AtomicBoolean flag = new AtomicBoolean(true);
        dictItemDataList.forEach(i -> {
            //查询是否存在值
            PhSysDictItem dictItem = this.getOne(Wrappers.lambdaQuery(PhSysDictItem.class).eq(PhSysDictItem::getType, i.getDictName())
                    .eq(PhSysDictItem::getValue, i.getValue()));

            if (dictItem != null) {
                //更新
                dictItem.setLabel(i.getValueName());
                boolean res = this.updateById(dictItem);
                if (res) {
                    log.info("商品中心-更新云商字典成功:{}", JSONObject.toJSONString(i));
                } else {
                    log.error("商品中心-更新云商字典失败:{}", JSONObject.toJSONString(i));
                    flag.set(false);
                    throw new BusinessRuntimeException(DICT_ITEM_DATA_UPDATE_EXCEPTION_800301);
                }
            } else {
                //插入
                PhSysDict dict = phSysDictService.getOne(Wrappers.lambdaQuery(PhSysDict.class).eq(PhSysDict::getType, i.getDictName()));
                if (dict == null) {
                    log.error("商品中心-添加云商字典失败，获取字典表数据为空:{}", JSONObject.toJSONString(i));
                    flag.set(false);
                    throw new BusinessRuntimeException(DICT_DATA_NOT_EXISTS_EXCEPTION_800303);
                } else {
                    PhSysDictItem phSysDictItem = new PhSysDictItem();
                    phSysDictItem.setValue(i.getValue())
                            .setLabel(i.getValueName())
                            .setType(i.getDictName())
                            .setDescription(dict.getDescription())
                            .setDictId(dict.getId());
                    boolean saveResult = this.save(phSysDictItem);
                    if (!saveResult) {
                        throw new BusinessRuntimeException(DICT_ITEM_DATA_SAVE_EXCEPTION_800302);
                    }
                    log.info("商品中心-添加云商字典成功:{}", JSONObject.toJSONString(i));
                }
            }
        });

        return flag.get();
    }

    private List<PhSysDictItem> getDictItemList(List<String> dictItemValueList, String type) {
        if (CollectionUtils.isEmpty(dictItemValueList)) {
            return null;
        }

        return this.list(Wrappers.lambdaQuery(PhSysDictItem.class)
                .eq(PhSysDictItem::getType, type)
                .in(PhSysDictItem::getValue, dictItemValueList));
    }

}
